#include "stdafx.h"
#include "ZipParser.h"
 


 
//create an XML document pointer from a file or
//as an empty dom document
MSXML2::IXMLDOMDocument3Ptr CZipParser::GetXMLDOMDocument(CStringW filePath)
{
	MSXML2::IXMLDOMDocument3Ptr returnValue = NULL;
	HRESULT hRes = returnValue.CreateInstance(__uuidof(MSXML2::FreeThreadedDOMDocument60)); 
	if(SUCCEEDED(hRes))
	{
		returnValue->async = VARIANT_FALSE;  
		returnValue->validateOnParse = VARIANT_FALSE;
		returnValue->resolveExternals = VARIANT_FALSE;
		returnValue->preserveWhiteSpace = VARIANT_FALSE;
		returnValue->setProperty(L"NewParser",VARIANT_TRUE);

		if (filePath.IsEmpty())
		{
			MSXML2::IXMLDOMProcessingInstructionPtr xmlIns = returnValue->createProcessingInstruction(L"xml",L"version='1.0' encoding='utf-8'");
			returnValue->appendChild(xmlIns);
		}
		else
		{
			CComBSTR pathBSTR(filePath.GetBuffer());
			VARIANT_BOOL docIsOk = returnValue->load((BSTR)pathBSTR);
			if(VARIANT_FALSE == docIsOk)
			{
				returnValue = NULL;
			}
		}

	}
	return returnValue;
}

//create an XML document pointer from an array of
//bytes, presumably from the zip file we are reading
MSXML2::IXMLDOMDocument3Ptr CZipParser::GetXMLDOMDocument(CHeapPtr<BYTE> memoryBuffer)
{
	MSXML2::IXMLDOMDocument3Ptr returnValue = NULL;
	MSXML2::IXMLDOMDocument3Ptr xmlDoc = NULL;

	HRESULT hRes = xmlDoc.CreateInstance(__uuidof(MSXML2::FreeThreadedDOMDocument60)); 
	if(SUCCEEDED(hRes))
	{
		xmlDoc->async = VARIANT_FALSE;  
		xmlDoc->validateOnParse = VARIANT_FALSE;
		xmlDoc->resolveExternals = VARIANT_FALSE;
		xmlDoc->preserveWhiteSpace = VARIANT_FALSE;
		xmlDoc->setProperty(L"NewParser",VARIANT_TRUE);

		//we want a BSTR to load the XML but our byte array
		//may be MultiByte or Unicode characters depending
		//on what system wrote them, so we will check for the
		//"<?xml" signature we expect to be the first bytes 
		int unicodeCharTest = ::CompareStringW(LOCALE_INVARIANT,
												NORM_IGNORECASE,
												(LPWSTR) memoryBuffer.m_pData,
												5,
												L"<?xml",
												5);
		VARIANT_BOOL docIsOk = VARIANT_FALSE;
		if(CSTR_EQUAL == unicodeCharTest)
		{
			_bstr_t xmlBSTR((LPWSTR) memoryBuffer.m_pData);
			docIsOk = returnValue->loadXML(xmlBSTR);
		}
		else
		{
			_bstr_t xmlBSTR((LPCSTR) memoryBuffer.m_pData);
			docIsOk = xmlDoc->loadXML(xmlBSTR);
		}
		//We need to reparse it just in case something squirly came in during
		//the zip/unzip process, this will clean up document problems
		hRes = returnValue.CreateInstance(__uuidof(MSXML2::FreeThreadedDOMDocument60)); 
		if(SUCCEEDED(hRes))
		{
			returnValue->async = VARIANT_FALSE;  
			returnValue->validateOnParse = VARIANT_FALSE;
			returnValue->resolveExternals = VARIANT_FALSE;
			returnValue->preserveWhiteSpace = VARIANT_FALSE;
			returnValue->setProperty(L"NewParser",VARIANT_TRUE);

			IXMLDOMDocument* rawDoc = NULL;
			hRes = returnValue->QueryInterface(IID_IXMLDOMDocument,reinterpret_cast<void**>(&rawDoc));
			if(SUCCEEDED(hRes))
			{


				_variant_t variantWrapper =rawDoc; 
				hRes = xmlDoc->save(variantWrapper);

				rawDoc->Release();
			}
		}
		if(FAILED(hRes)) returnValue = NULL;

	}
	 
	return returnValue;
}

